/**
 * Title:       FIPAMessageQueue.java
 * Copyright:   Copyright (c) 1996-2004 The Agent Factory Working Group. All rights reserved.
 * Licence:     This file is free software; you can redistribute it and/or modify
 *              it under the terms of the GNU Lesser General Public License as published by
 *              the Free Software Foundation; either version 2.1, or (at your option)
 *              any later version.
 *
 *              This file is distributed in the hope that it will be useful,
 *              but WITHOUT ANY WARRANTY; without even the implied warranty of
 *              MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *              GNU Lesser General Public License for more details.
 *
 *              You should have received a copy of the GNU Lesser General Public License
 *              along with Agent Factory; see the file COPYING.  If not, write to
 *              the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 *              Boston, MA 02111-1307, USA.
 */
package com.agentfactory.platform.mts;


import java.util.ArrayList;
import java.util.Vector;
import com.agentfactory.platform.core.AgentID;
import com.agentfactory.platform.core.Agent;
import java.util.Observable;

/**
 * This is a test class for the module implementation.  It contains a
 * single method that prints something to the screen.
 *
 * @author  Rem Collier
 */
public class FIPAMessageQueue extends Observable {
    private Agent agent;
    private ArrayList messageQueue = new ArrayList();
    
    public FIPAMessageQueue(Agent agent) {
        this.agent = agent;
    }
    
    /**
     * This method is used by FIPA Message Transport Services to deliver
     * new messages received to the relevant agents.  The method has been
     * synchronized to ensure that no messages are added whilst the agent
     * is gathering beliefs about the currently received messages.
     *
     * @param message a newly received FIPA message.
     */
    public synchronized void receiveMessage(Message message) {
        messageQueue.add(message);
        setChanged();
        notifyObservers(new MessageEvent(MessageEvent.RECEIVE, message));
    }
    
    /**
     * This method is used to send messages created by FIPA actuators.  It is
     * passed through the Message Queue because this provides a simple way of
     * capturing the events of sending and receiving a message.
     *
     * @param message the FIPA message to be sent.
     */
    public boolean sendMessage(Message message) {
        boolean sent = false;
        
        Vector services = agent.getAvailableMTSServices();
        MessageTransportService service = null;
        int serviceIndex = 0;
        String address = null;
        
        ArrayList addresses = null;
        
        // Loop through each of the receivers, and send the message on the
        // most appropriate MTS
        ArrayList receivers = message.getReceivers();
        for (int i = 0; i < receivers.size(); i++) {
            addresses = ((AgentID) receivers.get(i)).getAddresses();
            int addressIndex = 0;
        
            while (!sent && (addressIndex < addresses.size())) {
                address = (String) addresses.get(addressIndex++);
            
                service = null;
                serviceIndex = 0;
                while ((service == null) && (serviceIndex < services.size())) {
                    service = (MessageTransportService) services.elementAt(serviceIndex++);
                    if (!service.isValidService(address)) {
                        service = null;
                    }
                }
            
                if (service != null) {
                    sent = service.sendMessage(address, message);
                }
            }
        }

        if (sent) {
            setChanged();
            notifyObservers(new MessageEvent(MessageEvent.SEND, message));
        }

        return sent;
    }
    
    /**
     * This method generates an ArrayList of the Messages that were
     * received by an agent since the last check.  This method is
     * synchronized to ensure that no messages are added to the
     * queue whilst the message list is being generated.  The messages
     * added to this list are removed from the queue.
     *
     * @return an ArrayList of Strings that represent beliefs about the messages
     * received by the agent.
     */
    public synchronized ArrayList getMessages() {
        ArrayList messages = messageQueue;
        messageQueue = new ArrayList();
        return messages;
    }
    
    public synchronized ArrayList getMessages(String language) {
        ArrayList messages = new ArrayList();
        Message message = null;
        int index = 0;
        while (index < messageQueue.size()) {
            message = (Message) messageQueue.get(index);
            if (message.getLanguage().equals(language)) {
                messages.add(message);
                messageQueue.remove(message);
            } else {
                index++;
            }
        }
        return messages;
    }

    public synchronized boolean hasMessages() {
        return (messageQueue.size() > 0);
    }
    
    public synchronized ArrayList getMessageQueue() {
        return messageQueue;
    }
}
